package com.jeremyfeinstein.utils;

import android.os.Build;
import android.text.TextUtils;
import android.util.Log;

import com.github.nkzawa.emitter.Emitter;
import com.github.nkzawa.engineio.client.Transport;
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Manager;
import com.github.nkzawa.socketio.client.Socket;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.jeremyfeinstein.conference.YCHSConferenceClient;
import com.jeremyfeinstein.event.AddAudioStreamEvent;
import com.jeremyfeinstein.event.AddVideoStreamEvent;
import com.jeremyfeinstein.event.AllowTalkEvent;
import com.jeremyfeinstein.event.ApplyForSpeakerEvent;
import com.jeremyfeinstein.event.AttacheFileEvent;
import com.jeremyfeinstein.event.ChangeHostAssistListEvent;
import com.jeremyfeinstein.event.ChangeUserRoleEvent;
import com.jeremyfeinstein.event.ChatMessageEvent;
import com.jeremyfeinstein.event.CloseAudioStreamEvent;
import com.jeremyfeinstein.event.CloseMixStreamEvent;
import com.jeremyfeinstein.event.CloseVideoStreamEvent;
import com.jeremyfeinstein.event.ControlDeviceEvent;
import com.jeremyfeinstein.event.DisableAudioEvent;
import com.jeremyfeinstein.event.EditAliasNameEvent;
import com.jeremyfeinstein.event.EnableAudioEvent;
import com.jeremyfeinstein.event.EndMeetingEvent;
import com.jeremyfeinstein.event.ExitMeetingEvent;
import com.jeremyfeinstein.event.ForbidTalkEvent;
import com.jeremyfeinstein.event.GetMeetingUserListEvent;
import com.jeremyfeinstein.event.JoinEvent;
import com.jeremyfeinstein.event.SendMessageEvent;
import com.jeremyfeinstein.event.ShareVideoEvent;
import com.jeremyfeinstein.event.StartRecordEvent;
import com.jeremyfeinstein.event.StopShareEvent;
import com.jeremyfeinstein.event.TempRoomEvent;
import com.jeremyfeinstein.exception.YchsException;
import com.jeremyfeinstein.gson.ChatMessage;
import com.jeremyfeinstein.gson.JoinResponse;
import com.jeremyfeinstein.gson.MeetingUser;
import com.jeremyfeinstein.gson.OnResponse;
import com.jeremyfeinstein.gson.RecordFile;
import com.jeremyfeinstein.gson.SendMessage;
import com.jeremyfeinstein.gson.ShareVideo;
import com.jeremyfeinstein.listener.OnSocketListener;
import com.jeremyfeinstein.okhttputil.HSHostnameVerifier;
import com.jeremyfeinstein.okhttputil.HSTrustManager;
import com.jeremyfeinstein.okhttputil.Tls12SocketFactory;

import org.json.JSONArray;
import org.json.JSONObject;

import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import de.greenrobot.event.EventBus;

public class YCHSWebSocketAPI {
    // EventName
    public static String TYPE_Join = "Join";
    public static String TYPE_ChangeUserRole = "ChangeUserRole";
    public static String TYPE_GetMeetingUserList = "GetMeetingUserList";
    public static String TYPE_GetMeetingUserListAlone = "GetMeetingUserListAlone";
    public static String TYPE_ApplyForSpeaker = "ApplyForSpeaker";
    public static String TYPE_ApprovalForSpeaker = "ApprovalForSpeaker";
    public static String TYPE_TextMessageAccessControl = "TextMessageAccessControl";
    public static String TYPE_Dismiss = "dismiss";
    public static String TYPE_deleteVideoStream = "deleteVideoStream";
    public static String TYPE_addVideoStream = "addVideoStream";
    public static String TYPE_deleteAudioStream = "deleteAudioStream";
    public static String TYPE_addAudioStream = "addAudioStream";
    public static String TYPE_forbidTalkStream = "forbidTalkStream";
    public static String TYPE_allowTalkStream = "allowTalkStream";
    public static String TYPE_changeHostAssistList = "changeHostAssistList";
    public static String TYPE_DisableAudio = "DisableAudio";
    public static String TYPE_EndMeetingRoom = "EndMeetingRoom";
    public static String TYPE_ChatMessage = "ChatMessage";
    public static String TYPE_MeetingModeSetting = "MeetingModeSetting";
    public static String TYPE_LockMeetingRoom = "LockMeetingRoom";
    public static String TYPE_SendMessage = "SendMessage";
    public static String TYPE_EnableAudio = "EnableAudio";
    public static String TYPE_ShareVideo = "ShareVideo";
    public static String TYPE_StopShare = "StopShare";
    public static String TYPE_ExitMeeting = "ExitMeeting";
    public static String TYPE_AttacheFile = "AttacheFile";
    public static String TYPE_StartRecord = "StartRecord";
    public static String TYPE_CloseShare = "CloseShare";
    public static String TYPE_CtrlDevice = "CtrlDevice";
    public static String TYPE_ShowMixVideo = "ShowMixVideo";
    public static String TYPE_EditAliasName = "EditAliasName";
    public static String TYPE_KeepMeeting = "KeepMeeting";
    protected static final String TAG = YCHSWebSocketAPI.class.getSimpleName();
    private static YCHSWebSocketAPI instance;
    private String socketCookies;
    public Socket mSocket;
    public Socket mRemoteSocket;

    private Gson gson;

    private Transport transport;

    private OnSocketListener onSocketListener;
    private OnSocketListener onRemoteSocketListener;


    public void setOnSocketListener(OnSocketListener onSocketListener) {
        this.onSocketListener = onSocketListener;
    }

    public void setOnRemoteSocketListener(OnSocketListener onRemoteSocketListener) {
        this.onRemoteSocketListener = onRemoteSocketListener;
    }

    private YCHSWebSocketAPI() {
        gson = new Gson();
        socketCookies = YCHShttpAPI.getCookiesString();
    }

    public static YCHSWebSocketAPI getInstance() {
        //  if (instance == null) {
        //   synchronized (YCHSWebSocketAPI.class) {
        if (instance == null) {
            instance = new YCHSWebSocketAPI();
        }
        // }
        //}
        return instance;
    }

    /**
     * 初始化远程互动的socket
     */
    public void initRemoteSocket(String url) {
        try {
            X509TrustManager trustManager = new HSTrustManager();
            SSLContext s;
            s = SSLContext.getInstance("TLSv1.2");
            s.init(null, new TrustManager[]{trustManager},
                    new SecureRandom());
            SSLSocketFactory socketFactory = new Tls12SocketFactory(
                    s.getSocketFactory());
            HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);

            IO.setDefaultSSLContext(s);
            // sdk socket setting
            io.socket.client.IO.setDefaultSSLContext(s);
            HttpsURLConnection
                    .setDefaultHostnameVerifier(new HSHostnameVerifier());
            // mRemoteSocket = IO.socket(AppConstants.HTTP + ip + ":" + port);
            Log.d("jack", "YCHSWebSocketAPI: remoteSocketUrl==> " + url);
            mRemoteSocket = IO.socket(url);
            bindRemoteSocketIoCallbacks();
            bindRemoteCallbacks();
            mRemoteSocket.connect();
        }  catch (NoSuchAlgorithmException e){
            Log.e(TAG, "initRemoteSocket: NoSuchAlgorithmException "+e.getMessage());
        }catch (KeyManagementException e){
            Log.e(TAG, "initRemoteSocket: KeyManagementException "+e.getMessage());
        }catch (URISyntaxException e){
            Log.e(TAG, "initRemoteSocket: URISyntaxException "+e.getMessage());
        }
    }


    private void bindRemoteSocketIoCallbacks() {
        mRemoteSocket.io().on(Manager.EVENT_TRANSPORT, onTransportListener);
    }

    private void bindRemoteCallbacks() {
        mRemoteSocket.on(Socket.EVENT_MESSAGE, onRemoteMessageListener);
        mRemoteSocket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {

                if (onRemoteSocketListener != null){
                    onRemoteSocketListener.onConnectSuccess();
                }
            }
        });
        mRemoteSocket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {
                if (onRemoteSocketListener != null){
                    onRemoteSocketListener.onError(0, new YchsException("连接错误"));
                }
            }
        });
        mRemoteSocket.on(Socket.EVENT_CONNECT_TIMEOUT, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {

              //  Log.d("jack", "mRemoteSocket call: connect timeout");
                if (onRemoteSocketListener != null){
                    onRemoteSocketListener.onError(0, new YchsException("连接超时"));
                }
            }
        });
        mRemoteSocket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {

               // Log.d("jack", "mRemoteSocket call: disconnect");
                if (onRemoteSocketListener != null){
                    onRemoteSocketListener.onError(0, new YchsException("断开连接"));
                }
            }
        });
        mRemoteSocket.on(Socket.EVENT_ERROR, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {
               // Log.d("jack", "mRemoteSocket call: disconnect");
                if (onRemoteSocketListener != null){
                    onRemoteSocketListener.onError(0, new YchsException("未知错误"));
                }
            }
        });

    }


    /**
     * 初始化本地互动的socket
     */
    public void initSocket(String url) {
        X509TrustManager easyTrustManager = new HSTrustManager();
        SSLContext sslContext;
        try {
            sslContext = SSLContext.getInstance("TLSv1.2");
            sslContext.init(null, new TrustManager[]{easyTrustManager},
                    new SecureRandom());
            IO.setDefaultSSLContext(sslContext);
            io.socket.client.IO.setDefaultSSLContext(sslContext);
            HttpsURLConnection
                    .setDefaultHostnameVerifier(new HSHostnameVerifier());
            Log.d("jack", "YCHSWebSocketAPI: socketUrl==> " + url);
            mSocket = IO.socket(url);
            bindSocketIoCallbacks();
            bindCallbacks();
            mSocket.connect();
        }catch (NoSuchAlgorithmException e){
            Log.e(TAG, "initSocket: NoSuchAlgorithmException "+e.getMessage());
        }catch (KeyManagementException e){
            Log.e(TAG, "initSocket: KeyManagementException "+e.getMessage());
        }catch (URISyntaxException e){
            Log.e(TAG, "initSocket: URISyntaxException "+e.getMessage());
        }

    }

    private void bindSocketIoCallbacks() {
        mSocket.io().on(Manager.EVENT_TRANSPORT, onTransportListener);
    }

    private void bindCallbacks() {
        mSocket.on(Socket.EVENT_MESSAGE, onMessageListener);
        mSocket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {

                Log.d("jack", "mSocket call: connected");
                if (onSocketListener != null){
                    onSocketListener.onConnectSuccess();
                }
            }
        });
        mSocket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {
                Log.d("jack", "mSocket call: connect error");
                if (onSocketListener != null){
                    onSocketListener.onError(0, new YchsException("连接错误"));
                }
            }
        });
        mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {

                Log.d("jack", "mSocket call: connect timeout");
                if (onSocketListener != null){
                    onSocketListener.onError(0, new YchsException("连接超时"));
                }
            }
        });
        mSocket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {
                Log.d("jack", "mSocket call: disconnect");
                if (onSocketListener != null){
                    onSocketListener.onError(0, new YchsException("断开连接"));
                }
            }
        });
        mSocket.on(Socket.EVENT_ERROR, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {
                Log.d("jack", "mSocket call: disconnect");
                if (onSocketListener != null){
                    onSocketListener.onError(0, new YchsException("未知错误"));
                }
            }
        });

    }

    private Emitter.Listener onTransportListener = new Emitter.Listener() {
        @Override
        public void call(Object... objects) {
            transport = (Transport) objects[0];
            if (objects.length > 0 && objects[0] instanceof Transport) {
                transport = (Transport) objects[0];
                bindTransport();
            }
        }
    };

    private void bindTransport() {
        if (transport != null) {
            transport.on(Transport.EVENT_REQUEST_HEADERS, onRequestHeaderListener);
            transport.on(Transport.EVENT_RESPONSE_HEADERS, onResponseHeaderListener);
        }
    }

    private Emitter.Listener onResponseHeaderListener = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            if (args.length > 0 && args[0] instanceof Map) {
                final Map<String, String> headers = (Map<String, String>) args[0];
                String cookie = headers.get("Set-Cookie");
                if (!TextUtils.isEmpty(socketCookies) && !socketCookies.contains("io")) {
                    socketCookies += cookie + ";";
                }
            }
        }
    };


    private Emitter.Listener onRequestHeaderListener = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            if (args.length > 0 && args[0] instanceof Map) {
                Map<String, String> header = (Map<String, String>) args[0];
                header.put("cookie", socketCookies);
            }
        }
    };


    private Emitter.Listener onMessageListener = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            JSONObject json = (JSONObject) args[0];
           // Log.e("onMessageListener", args + " " + json);
            Log.e("----", args + " " + json);
            try {
                String type = json.getString("type");
                if (TYPE_GetMeetingUserList.equals(type) || TYPE_GetMeetingUserListAlone.equals(type)) {
                    GetMeetingUserListEvent event = new GetMeetingUserListEvent();
                    JSONArray userList = json.getJSONArray("userList");
                    List<MeetingUser> meetingUsers = new ArrayList<MeetingUser>();
                    MeetingUser meetingUser;
                    Gson gson = new GsonBuilder().create();
                    for (int i = 0; i < userList.length(); i++) {
                        meetingUser = gson.fromJson(userList.get(i).toString(), MeetingUser.class);
                        meetingUsers.add(meetingUser);
                    }
                    event.setUserList(meetingUsers);
                    EventBus.getDefault().post(event);
                } else if (TYPE_ExitMeeting.equals(type)) {
                    ExitMeetingEvent event = new ExitMeetingEvent();
                    JSONArray userList = json.getJSONArray("userList");
                    String userCode = json.getString("userCode");
                    String message = json.getString("message");
                    List<MeetingUser> meetingUsers = new ArrayList<MeetingUser>();
                    MeetingUser meetingUser;
                    Gson gson = new GsonBuilder().create();
                    for (int i = 0; i < userList.length(); i++) {
                        meetingUser = gson.fromJson(userList.get(i).toString(), MeetingUser.class);
                        meetingUsers.add(meetingUser);
                    }
                    event.setUserCode(userCode);
                    event.setMessage(message);
                    event.setUserList(meetingUsers);
                    EventBus.getDefault().post(event);
                } else if (TYPE_MeetingModeSetting.equals(type)) {
                    TempRoomEvent event = gson.fromJson(json.toString(),
                            TempRoomEvent.class);
                    EventBus.getDefault().post(event);
                } else if (TYPE_forbidTalkStream.equals(type)) {
                    ForbidTalkEvent event = gson.fromJson(json.toString(),
                            ForbidTalkEvent.class);
                    EventBus.getDefault().post(event);
                } else if (TYPE_allowTalkStream.equals(type)) {
                    AllowTalkEvent event = gson.fromJson(json.toString(), AllowTalkEvent.class);
                    EventBus.getDefault().post(event);
                } else if (TYPE_ChatMessage.equals(type)) {

                    ChatMessageEvent event = new ChatMessageEvent();
                    ChatMessage chatMessage;
                    Gson gson = new GsonBuilder().create();
                    Log.e("chatmessage", json.toString());
                    chatMessage = gson.fromJson(json.toString(), ChatMessage.class);
                    event.setChatMessage(chatMessage);
                    EventBus.getDefault().post(event);

                } else if (TYPE_SendMessage.equals(type)) {
                    SendMessageEvent event = new SendMessageEvent();
                    JSONArray messageList = json.getJSONArray("messageList");
                    SendMessage sendMessage;
                    for (int i = 0; i < messageList.length(); i++) {
                        sendMessage = gson.fromJson(messageList.get(i)
                                .toString(), SendMessage.class);
                        ConfigUtil.getInstance().setMobileId(
                                sendMessage.getMOBILE_ID());
                        YCHSInstance.getInstance().addSendMessages(sendMessage);
                    }
                    if (messageList.length() > 0) {
                        EventBus.getDefault().post(event);
                    }
                } else if (TYPE_Join.equals(type)) {
                    JoinEvent event = new JoinEvent();
                    JoinResponse joinResponse = gson.fromJson(json.toString(),
                            JoinResponse.class);
                    event.setJoinResponse(joinResponse);
                    EventBus.getDefault().post(event);
                } else if (TYPE_AttacheFile.equals(type)) {
                    AttacheFileEvent event = new AttacheFileEvent();
                    OnResponse onResponse = gson.fromJson(json.toString(),
                            OnResponse.class);
                    event.setOnResponse(onResponse);
                    EventBus.getDefault().post(event);
                } else if (TYPE_DisableAudio.equals(type)) {
                    DisableAudioEvent event = gson.fromJson(json.toString(),
                            DisableAudioEvent.class);
                    EventBus.getDefault().post(event);
                } else if (TYPE_EnableAudio.equals(type)) {
                    EnableAudioEvent event = gson.fromJson(json.toString(),
                            EnableAudioEvent.class);
                    EventBus.getDefault().post(event);
                } else if (TYPE_ShareVideo.equals(type)) {
                    ShareVideoEvent event = new ShareVideoEvent();
                    ShareVideo shareVideo = gson.fromJson(json.toString(),
                            ShareVideo.class);
                    event.setShareVideo(shareVideo);
                    EventBus.getDefault().post(event);
                } else if (TYPE_StopShare.equals(type)
                        || TYPE_CloseShare.equals(type)) {
                    StopShareEvent event = new StopShareEvent();
                    if (json.has("shareWhiteboard")) {
                        event.setShareWhiteboard(true);
                    } else {
                        event.setShareWhiteboard(false);
                    }
                    EventBus.getDefault().post(event);
                } else if (TYPE_changeHostAssistList.equals(type)) {
                    ChangeHostAssistListEvent event = new ChangeHostAssistListEvent();
                    EventBus.getDefault().post(event);
                } else if (TYPE_ChangeUserRole.equals(type)) {
                    ChangeUserRoleEvent event = new ChangeUserRoleEvent();
                    event.setMeetingId(json.getString("meetingId"));
                    event.setNoticeType(json.getString("noticeType"));
                    event.setStatus(json.getString("status"));
                    if (json.has("newRole")) {
                        event.setNewRole(json.getString("newRole"));
                    }
                    event.setUserCode(json.getString("USER_CODE"));
                    if (json.has("addVideoUser")) {
                        event.setAddVideoUser(json.getString("addVideoUser"));
                    }
                    if (json.has("replaceRegion")) {
                        event.setReplaceRegion(json.getString("replaceRegion"));
                    }

                    EventBus.getDefault().post(event);
                } else if (TYPE_ApplyForSpeaker.equals(type)) {
                    ApplyForSpeakerEvent event = new ApplyForSpeakerEvent();
                    event.setMeetingId(json.getString("meetingId"));
                    event.setUserCode(json.getString("userCode"));
                    EventBus.getDefault().post(event);
                } else if (TYPE_addVideoStream.equals(type)) {
                    AddVideoStreamEvent event = new AddVideoStreamEvent();
                    event.setUserCode(json.getString("userCode"));
                    Log.d("----", "AddVideo");
                    EventBus.getDefault().post(event);
                } else if (TYPE_deleteVideoStream.equals(type)) {
                    CloseVideoStreamEvent event = new CloseVideoStreamEvent();
                    event.setUserCode(json.getString("userCode"));
                    // event.setStreamId(json.getString("streamId"));
                    Log.d("----", "DeleteVideo");
                    EventBus.getDefault().post(event);
                } else if (TYPE_deleteAudioStream.equals(type)) {
                    CloseAudioStreamEvent event = new CloseAudioStreamEvent();
                    event.setUserCode(json.getString("userCode"));
                    Log.d("----", "DeleteAudio");
                    EventBus.getDefault().post(event);
                } else if (TYPE_addAudioStream.equals(type)) {
                    AddAudioStreamEvent event = new AddAudioStreamEvent();
                    event.setUserCode(json.getString("userCode"));
                    EventBus.getDefault().post(event);
                    Log.d("----", "AddAudio");
                } else if (TYPE_EndMeetingRoom.equals(type)) {
                    EndMeetingEvent event = new EndMeetingEvent();
                    if (json.has("resultCode")) {
                        event.setResultCode(json.getInt("resultCode"));
                    }
                    if (json.has("errorMessage")) {
                        event.setErrorMessage(json.getString("errorMessage"));
                    }
                    if (json.has("message")) {
                        event.setMessage(json.getString("message"));
                    }
                    if (json.has("err")) {
                        event.setErr(json.getString("err"));
                    }
                    EventBus.getDefault().post(event);
                } else if (TYPE_StartRecord.equals(type)) {
                    RecordFile file = gson.fromJson(json.getString("file"),
                            RecordFile.class);
                    StartRecordEvent event = new StartRecordEvent();
                    event.setFile(file);
                    EventBus.getDefault().post(event);
                } else if (TYPE_CtrlDevice.equals(type)) {
                    String eventStr = json.getString("event");
                    ControlDeviceEvent event = new ControlDeviceEvent();
                    event.setEvent(eventStr);
                    String Sstatus = json.getString("status");
                    event.setStatus("start".equals(Sstatus) ? 1 : 0);
                    event.setSpeed(0x3e);
                    EventBus.getDefault().post(event);
                } else if (TYPE_ShowMixVideo.equals(type)) {
                    String action = json.getString("action");
                    CloseMixStreamEvent event = new CloseMixStreamEvent();
                    event.setAction(action);
                    event.setUserCode(json.getString("userCode"));
                    EventBus.getDefault().post(event);
                } else if (TYPE_EditAliasName.equals(type)) {
                    EditAliasNameEvent event = new EditAliasNameEvent();
                    event.setAliasName(json.getString("aliasName"));
                    event.setUserCode(json.getString("userCode"));
                    event.setResultCode(json.getInt("resultCode") + "");
//                    event.setErrorMessage(json.getString("errorMessage"));
//                    event.setErr(json.getString("err"));
                    EventBus.getDefault().post(event);
                }
            } catch (Exception e) {
                // TODO: handle exception
            }

        }
    };

    private Emitter.Listener onRemoteMessageListener = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            JSONObject json = (JSONObject) args[0];
            Log.e("onMessageListener", args + " " + json);
            try {
                String type = json.getString("type");
                if (TYPE_GetMeetingUserList.equals(type) || TYPE_GetMeetingUserListAlone.equals(type)) {
                    GetMeetingUserListEvent event = new GetMeetingUserListEvent();
                    JSONArray userList = json.getJSONArray("userList");
                    List<MeetingUser> meetingUsers = new ArrayList<MeetingUser>();
                    MeetingUser meetingUser;
                    Gson gson = new GsonBuilder().create();
                    for (int i = 0; i < userList.length(); i++) {
                        meetingUser = gson.fromJson(userList.get(i).toString(), MeetingUser.class);
                        meetingUsers.add(meetingUser);
                    }
                    event.setUserList(meetingUsers);
                    EventBus.getDefault().post(event);
                } else if (TYPE_ExitMeeting.equals(type)) {
                    ExitMeetingEvent event = new ExitMeetingEvent();
                    JSONArray userList = json.getJSONArray("userList");
                    String userCode = json.getString("userCode");
                    String message = json.getString("message");
                    List<MeetingUser> meetingUsers = new ArrayList<MeetingUser>();
                    MeetingUser meetingUser;
                    Gson gson = new GsonBuilder().create();
                    for (int i = 0; i < userList.length(); i++) {
                        meetingUser = gson.fromJson(userList.get(i).toString(),
                                MeetingUser.class);
                        meetingUsers.add(meetingUser);
                    }
                    event.setUserCode(userCode);
                    event.setMessage(message);
                    event.setUserList(meetingUsers);
                    EventBus.getDefault().post(event);
                } else if (TYPE_MeetingModeSetting.equals(type)) {
                    TempRoomEvent event = gson.fromJson(json.toString(),
                            TempRoomEvent.class);
                    EventBus.getDefault().post(event);
                } else if (TYPE_forbidTalkStream.equals(type)) {
                    ForbidTalkEvent event = gson.fromJson(json.toString(),
                            ForbidTalkEvent.class);
                    EventBus.getDefault().post(event);
                } else if (TYPE_allowTalkStream.equals(type)) {
                    AllowTalkEvent event = gson.fromJson(json.toString(), AllowTalkEvent.class);
                    EventBus.getDefault().post(event);
                } else if (TYPE_ChatMessage.equals(type)) {
                    ChatMessageEvent event = new ChatMessageEvent();
                    ChatMessage chatMessage;
                    Gson gson = new GsonBuilder().create();
                    Log.e("chatmessage", json.toString());
                    chatMessage = gson.fromJson(json.toString(), ChatMessage.class);
                    event.setChatMessage(chatMessage);
                    EventBus.getDefault().post(event);
                } else if (TYPE_Join.equals(type)) {
                    JoinEvent event = new JoinEvent();
                    JoinResponse joinResponse = gson.fromJson(json.toString(), JoinResponse.class);
                    event.setJoinResponse(joinResponse);
                    EventBus.getDefault().post(event);
                } else if (TYPE_AttacheFile.equals(type)) {
                    AttacheFileEvent event = new AttacheFileEvent();
                    OnResponse onResponse = gson.fromJson(json.toString(),
                            OnResponse.class);
                    event.setOnResponse(onResponse);
                    EventBus.getDefault().post(event);
                } else if (TYPE_DisableAudio.equals(type)) {
                    DisableAudioEvent event = gson.fromJson(json.toString(),
                            DisableAudioEvent.class);
                    EventBus.getDefault().post(event);
                } else if (TYPE_EnableAudio.equals(type)) {
                    EnableAudioEvent event = gson.fromJson(json.toString(),
                            EnableAudioEvent.class);
                    EventBus.getDefault().post(event);
                } else if (TYPE_ShareVideo.equals(type)) {
                    ShareVideoEvent event = new ShareVideoEvent();
                    ShareVideo shareVideo = gson.fromJson(json.toString(),
                            ShareVideo.class);
                    event.setShareVideo(shareVideo);
                    EventBus.getDefault().post(event);
                } else if (TYPE_StopShare.equals(type)
                        || TYPE_CloseShare.equals(type)) {
                    StopShareEvent event = new StopShareEvent();
                    if (json.has("shareWhiteboard")) {
                        event.setShareWhiteboard(true);
                    } else {
                        event.setShareWhiteboard(false);
                    }
                    EventBus.getDefault().post(event);
                } else if (TYPE_changeHostAssistList.equals(type)) {
                    ChangeHostAssistListEvent event = new ChangeHostAssistListEvent();
                    EventBus.getDefault().post(event);
                } else if (TYPE_ChangeUserRole.equals(type)) {
                    ChangeUserRoleEvent event = new ChangeUserRoleEvent();
                    event.setMeetingId(json.getString("meetingId"));
                    event.setNoticeType(json.getString("noticeType"));
                    event.setStatus(json.getString("status"));
                    event.setNewRole(json.getString("newRole"));
                    event.setUserCode(json.getString("USER_CODE"));
                    EventBus.getDefault().post(event);
                } else if (TYPE_ApplyForSpeaker.equals(type)) {
                    ApplyForSpeakerEvent event = new ApplyForSpeakerEvent();
                    event.setMeetingId(json.getString("meetingId"));
                    event.setUserCode(json.getString("userCode"));
                    EventBus.getDefault().post(event);
                } else if (TYPE_addVideoStream.equals(type)) {
                    AddVideoStreamEvent event = new AddVideoStreamEvent();
                    event.setUserCode(json.getString("userCode"));
                    Log.d("Video", "addAudio");
                    EventBus.getDefault().post(event);
                } else if (TYPE_deleteVideoStream.equals(type)) {
                    CloseVideoStreamEvent event = new CloseVideoStreamEvent();
                    event.setUserCode(json.getString("userCode"));
                    // event.setStreamId(json.getString("streamId"));
                    Log.d("Video", "DeleteVideo");
                    EventBus.getDefault().post(event);
                } else if (TYPE_deleteAudioStream.equals(type)) {
                    CloseAudioStreamEvent event = new CloseAudioStreamEvent();
                    event.setUserCode(json.getString("userCode"));
                    Log.d("Audio", "DeleteAudio");
                    EventBus.getDefault().post(event);
                } else if (TYPE_addAudioStream.equals(type)) {
                    AddAudioStreamEvent event = new AddAudioStreamEvent();
                    event.setUserCode(json.getString("userCode"));
                    Log.d("Audio", "addAudio");
                    EventBus.getDefault().post(event);
                } else if (TYPE_EndMeetingRoom.equals(type)) {
                    EndMeetingEvent event = new EndMeetingEvent();
                    if (json.has("resultCode")) {
                        event.setResultCode(json.getInt("resultCode"));
                    }
                    if (json.has("errorMessage")) {
                        event.setErrorMessage(json.getString("errorMessage"));
                    }
                    if (json.has("message")) {
                        event.setMessage(json.getString("message"));
                    }
                    if (json.has("err")) {
                        event.setErr(json.getString("err"));
                    }

                    EventBus.getDefault().post(event);
                } else if (TYPE_StartRecord.equals(type)) {
                    RecordFile file = gson.fromJson(json.getString("file"),
                            RecordFile.class);
                    StartRecordEvent event = new StartRecordEvent();
                    event.setFile(file);
                    EventBus.getDefault().post(event);
                }
            } catch (Exception e) {
                // TODO: handle exception
                Log.e(TAG, "call: ", e);
            }

        }
    };

    public void sendSocketMessage(final JSONObject jsonObject) {
        // Log.d("jack", "sendSocketMessage :" + jsonObject.toString());
        if (AppConstants.isLocalMeeting) {
            if (mSocket != null && mSocket.connected()){
                Log.d("jack", "sendSocketMessage: mSocket connect");
                mSocket.emit("message", jsonObject);
            }else {
                //  Log.e("jack", "sendSocketMessage:  mSocket disconnect");
            }
        } else {
            if (mRemoteSocket != null && mRemoteSocket.connected()){
                //  Log.d("jack", "sendSocketMessage: mRemoteSocket connect");
                mRemoteSocket.emit("message", jsonObject);
            }else {
                //Log.e("jack", "sendSocketMessage: mRemoteSocket disconnect");
            }
        }
    }

    public void setSocketCookies(String socketCookies) {
        this.socketCookies = socketCookies;
    }

    public String getSocketCookies() {
        return socketCookies;
    }



    public void closeSocket() {
        if (instance != null) {
            instance = null;
        }
        try {
            if (mSocket != null) {//针对北京电科院联想手机，如果是联想手机，退出互动出现 SSL==null,导致奔溃
                if (!"Lenovo".equals(Build.MANUFACTURER)) {
                     mSocket.disconnect();
                }
                mSocket.off();
                mSocket = null;
            }
            if (mRemoteSocket != null) {
                mRemoteSocket.disconnect();
                mSocket.off();
                mRemoteSocket = null;
            }
        } catch (Exception e) {
            Log.e(TAG, "closeSocket error ");
        }
    }


    public boolean isSocketConnected(){
        return mSocket != null && mSocket.connected();
    }

    public boolean isRemoteSocketConnected(){
        return mRemoteSocket != null && mRemoteSocket.connected();
    }

    public void disconnectSocket(){
        if (mSocket != null) {
            mSocket.disconnect();
            mSocket.off();
            mSocket.io().off();
        }
    }

    public void disconnectRemoteSocket(){
        if (mRemoteSocket != null) {
            mRemoteSocket.disconnect();
            mRemoteSocket.off();
            mRemoteSocket.io().off();
        }
    }

    /**
     * 获取参会人员列表
     *
     * @param meetingId
     */
    public void getMeetingUserList(String meetingId) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_GetMeetingUserList);
            jobj.put("meetingId", meetingId);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送打开和关闭视频流
     *
     * @param action
     */
    public void contrlMixVideo(String action) {
        try {
            String userCode = YCHSInstance.getInstance().getLoginUser().getUSER_CODE();
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_ShowMixVideo);
            jobj.put("meetingId", YCHSConferenceClient.getInstance().getMeetingId());
            jobj.put("userCode", userCode);
            jobj.put("action", action);
            jobj.put("controlUserCode", userCode);
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取参会人员列表Alone
     *
     * @param meetingId
     */
    public void getMeetingUserListAlone(String meetingId) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_GetMeetingUserListAlone);
            jobj.put("meetingId", meetingId);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 修改参会人员视频顶部的别名
     *
     * @param meetingId
     */
    public void editAliasName(String meetingId, String userCode, String aliasName) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_EditAliasName);
            jobj.put("meetingId", meetingId);
            jobj.put("userCode", userCode);
            jobj.put("aliasName", aliasName);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送布控球控制广播
     *
     * @param status
     * @param action
     */
    public void controlDevice(String status, String action, String userCode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_CtrlDevice);
            jobj.put("action", status);
            jobj.put("event", action);
            jobj.put("userCode", userCode);
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 加入互动
     */
    public void join(String meetingId, String streamId, String role, String falg) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_Join);
            jobj.put("meetingId", meetingId);
            if ("1".equals(falg)) {
                jobj.put("mobileId", "");
            } else if ("2".equals(falg)) {
                jobj.put("mobileId", ConfigUtil.getInstance().getMobileId());
            }
            jobj.put("streamId", streamId);
            jobj.put("userCode", YCHSInstance.getInstance().getLoginUser()
                    .getUSER_CODE());
            jobj.put("role", role);
            jobj.put("userName", "U"
                    + YCHSInstance.getInstance().getLoginUser().getUSER_CODE());
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 申请主讲
     */
    public void applyForSpeaker(String meetingId, String userCode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_ApplyForSpeaker);
            jobj.put("meetingId", meetingId);
            jobj.put("userCode", userCode);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 互动讨论
     */
    public void chatMessage(ChatMessage chatMessage) {
        try {
            String chatString = new GsonBuilder().create().toJson(chatMessage);
            JSONObject jobj = new JSONObject(chatString);
            jobj.put("type", TYPE_ChatMessage);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 设置参会人员角色
     */
    public void changeUserRole(String meetingId, String userCode,
                               String roleCode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_ChangeUserRole);
            jobj.put("meetingId", meetingId);
            jobj.put("userCode", userCode);
            jobj.put("roleCode", roleCode);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 申请主讲审批
     */
    public void approvalForSpeaker(String meetingId, String userCode,
                                   String result) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_ApprovalForSpeaker);
            jobj.put("meetingId", meetingId);
            jobj.put("userCode", userCode);
            jobj.put("result", result);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 请出互动室
     */
    public void dismiss(String meetingId, String userCode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_Dismiss);
            jobj.put("meetingId", meetingId);
            jobj.put("userCode", userCode);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 互动模式设定
     */
    public void meetingModeSetting(String meetingId, String mode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_MeetingModeSetting);
            jobj.put("meetingId", meetingId);
            jobj.put("mode", mode);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 锁定互动室
     */
    public void lockMeetingRoom(String meetingId, String lock) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_LockMeetingRoom);
            jobj.put("meetingId", meetingId);
            jobj.put("lock", lock);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 关闭用户音频
     */
    public void deleteAudioStream(String meetingId, String userCode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_deleteAudioStream);
            jobj.put("meetingId", meetingId);
            jobj.put("userCode", userCode);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 打开用户音频
     */
    public void addAudioStream(String meetingId, String userCode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_addAudioStream);
            jobj.put("meetingId", meetingId);
            jobj.put("userCode", userCode);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 关闭用户视频
     */
    public void deleteVideoStream(String meetingId, String userCode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_deleteVideoStream);
            jobj.put("meetingId", meetingId);
            jobj.put("userCode", userCode);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 打开用户视频
     */
    public void addVideoStream(String meetingId, String userCode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_addVideoStream);
            jobj.put("meetingId", meetingId);
            jobj.put("userCode", userCode);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 静音
     */
    public void disableAudio(String streamId, String userCode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_DisableAudio);
            jobj.put("streamId", streamId);
            jobj.put("userCode", userCode);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            jobj.put("meetingId", YCHSConferenceClient.getInstance().getMeetingId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 关闭互动室
     */
    public void endMeetingRoom(String meetingId, String flag) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_EndMeetingRoom);
            jobj.put("meetingId", meetingId);
            jobj.put("flag", flag);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 打开音频
     */
    public void enableAudio(String streamId,String userCode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_EnableAudio);
            jobj.put("streamId", streamId);
            jobj.put("userCode", userCode);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            jobj.put("meetingId", YCHSConferenceClient.getInstance().getMeetingId());

            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 更改主持人/助理控制图标
     */
    public void changeHostAssistList(String meetingId, String status,
                                     String userCode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_changeHostAssistList);
            jobj.put("meetingId", meetingId);
            jobj.put("status", status);
            jobj.put("userCode", userCode);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 离开互动
     */
    public void exitMeeting(String meetingId) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_ExitMeeting);
            jobj.put("meetingId", meetingId);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 分享互动室
     */
    public void shareVideo(String streamId, String room, String beShareUserCode) {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_ShareVideo);
            jobj.put("streamId", streamId);
            jobj.put("room", room);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            jobj.put("meetingId", YCHSConferenceClient.getInstance()
                    .getMeetingId());
            jobj.put("beShareUserCode", beShareUserCode);
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 停止分享
     */
    public void stopShare() {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_StopShare);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传附件通知
     */
    public void attacheFile() {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_AttacheFile);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 发送消息，防止会议出现未登录现象导致session丢失
     */
    public void keepMeetingByIntervalTime() {
        try {
            JSONObject jobj = new JSONObject();
            jobj.put("type", TYPE_KeepMeeting);
            jobj.put("sessionid", ConfigUtil.getInstance().getSessionId());
            sendSocketMessage(jobj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
